
package org.apache.solr.search;

import org.apache.lucene.search.Filter;
import org.apache.lucene.util.OpenBitSet;
import org.apache.solr.common.SolrException;

/**
 * <code>DocSet</code> represents an unordered set of Lucene Document Ids.
 *
 * <p>
 * WARNING: Any DocSet returned from SolrIndexSearcher should <b>not</b> be modified as it may have been retrieved from
 * a cache and could be shared.
 * </p>
 *
 *
 * @since solr 0.9
 */
public interface DocSet /* extends Collection<Integer> */ {

    /**
     * Adds the specified document if it is not currently in the DocSet
     * (optional operation).
     *
     * @see #addUnique
     * @throws SolrException if the implementation does not allow modifications
     */
    public void add(int doc);

    /**
     * Adds a document the caller knows is not currently in the DocSet (optional
     * operation).
     *
     * <p> This method may be faster then
     * <code>add(doc)</code> in some implementaions provided the caller is
     * certain of the precondition. </p>
     *
     * @see #add
     * @throws SolrException if the implementation does not allow modifications
     */
    public void addUnique(int doc);

    /**
     * Returns the number of documents in the set.
     */
    public int size();

    /**
     * Returns true if a document is in the DocSet.
     */
    public boolean exists(int docid);

    /**
     * Returns an iterator that may be used to iterate over all of the documents
     * in the set.
     *
     * <p> The order of the documents returned by this iterator is
     * non-deterministic, and any scoring information is meaningless </p>
     */
    public DocIterator iterator();

    /**
     * Returns a BitSet view of the DocSet. Any changes to this BitSet
     * <b>may</b> be reflected in the DocSet, hence if the DocSet is shared or
     * was returned from a SolrIndexSearcher method, it's not safe to modify the
     * BitSet.
     *
     * @return An OpenBitSet with the bit number of every docid set in the set.
     */
    public OpenBitSet getBits();

    /**
     * Returns the approximate amount of memory taken by this DocSet. This is
     * only an approximation and doesn't take into account java object overhead.
     *
     * @return the approximate memory consumption in bytes
     */
    public long memSize();

    /**
     * Returns the intersection of this set with another set. Neither set is
     * modified - a new DocSet is created and returned.
     *
     * @return a DocSet representing the intersection
     */
    public DocSet intersection(DocSet other);

    /**
     * Returns the number of documents of the intersection of this set with
     * another set. May be more efficient than actually creating the
     * intersection and then getting it's size.
     */
    public int intersectionSize(DocSet other);

    /**
     * Returns true if these sets have any elements in common
     */
    public boolean intersects(DocSet other);

    /**
     * Returns the union of this set with another set. Neither set is modified -
     * a new DocSet is created and returned.
     *
     * @return a DocSet representing the union
     */
    public DocSet union(DocSet other);

    /**
     * Returns the number of documents of the union of this set with another
     * set. May be more efficient than actually creating the union and then
     * getting it's size.
     */
    public int unionSize(DocSet other);

    /**
     * Returns the documents in this set that are not in the other set. Neither
     * set is modified - a new DocSet is created and returned.
     *
     * @return a DocSet representing this AND NOT other
     */
    public DocSet andNot(DocSet other);

    /**
     * Returns the number of documents in this set that are not in the other
     * set.
     */
    public int andNotSize(DocSet other);

    /**
     * Returns a Filter for use in Lucene search methods, assuming this DocSet
     * was generated from the top-level MultiReader that the Lucene search
     * methods will be invoked with.
     */
    public Filter getTopFilter();

    /**
     * Takes the docs from this set and sets those bits on the target
     * OpenBitSet. The target should be sized large enough to accommodate all of
     * the documents before calling this method.
     */
    public void setBitsOn(OpenBitSet target);
    public static DocSet EMPTY = new SortedIntDocSet(new int[0], 0);
}
